/*******************************************************************************
* Copyright (c) 2010, 2018 西安秦晔信息科技有限公司
* Licensed under the Apache License, Version 2.0 (the "License");
*    you may not use this file except in compliance with the License.
*    You may obtain a copy of the License at
*
*       http://www.apache.org/licenses/LICENSE-2.0
*
*    Unless required by applicable law or agreed to in writing, software
*    distributed under the License is distributed on an "AS IS" BASIS,
*    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*    See the License for the specific language governing permissions and
*    limitations under the License.
*******************************************************************************/
package com.qinyeit.serviceapp.service.organization.impl;

import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Lists;
import com.qinyeit.serviceapp.entity.Branch;
import com.qinyeit.serviceapp.entity.DishesMenu;
import com.qinyeit.serviceapp.entity.DishesMenuBranch;
import com.qinyeit.serviceapp.entity.MerchantGroup;
import com.qinyeit.serviceapp.entity.enums.Industries;
import com.qinyeit.serviceapp.entity.enums.PropType;
import com.qinyeit.serviceapp.entity.enums.State;
import com.qinyeit.serviceapp.exception.BusinessRunTimeException;
import com.qinyeit.serviceapp.redis.RedisKeyHelper;
import com.qinyeit.serviceapp.repository.organization.BranchRepository;
import com.qinyeit.serviceapp.service.branchs.BranchDataReleasedServiceImpl;
import com.qinyeit.serviceapp.service.dishes.DishesMenuBranchService;
import com.qinyeit.serviceapp.service.dishes.DishesMenuService;
import com.qinyeit.serviceapp.service.organization.BranchService;
import com.qinyeit.serviceapp.service.organization.MerchantGroupService;
import com.qinyeit.serviceapp.service.thirdpart.BranchPlatformApiServiceImpl;
import com.qinyeit.serviceapp.utils.SearchUtils;
import com.qinyetech.springstage.core.date.DateUtils;
import com.qinyetech.springstage.core.entity.search.Searchable;
import com.qinyetech.springstage.core.lang.QyMap;
import com.qinyetech.springstage.core.lang.StringUtils;
import com.qinyetech.springstage.core.repository.jdbc.PageNamedParameterJdbcTemplate;
import com.qinyetech.springstage.core.service.BaseService;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.BoundHashOperations;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;

/** 
 * ClassName: BranchServiceImpl <br/> 
 * Function: 分店 业务实现 <br/> 
 * date: 2018-11-21 15:03:05 <br/> 
 * 
 * @author liuwenjin
 * @version 1.0
 * @since JDK 1.8
 */
@Service
@Transactional
public class BranchServiceImpl extends BaseService<Branch, Long> implements BranchService {


	@Autowired
	private BranchRepository branchRepository;
	@Autowired
	private MerchantInitServiceImpl merchantInitService;
	@Autowired
	private StringRedisTemplate stringRedisTemplate;
	@Autowired
	private PageNamedParameterJdbcTemplate jdbcTemplate;
	@Autowired
	private BranchPlatformApiServiceImpl branchPlatformApiService;
	@Autowired
	private MerchantGroupService merchantGroupService;
	@Autowired
	private BranchDataReleasedServiceImpl branchDataReleasedService;
	@Autowired
	private DishesMenuService dishesMenuService;
	@Autowired
	private DishesMenuBranchService dishesMenuBranchService;

	@Transactional
	@Override
	public Branch updateBranch(Branch branch,String password) {
		MerchantGroup merchantGroup = merchantGroupService.findById(branch.getMerchantGroupId());
		Long merchantId = branchPlatformApiService.createBranchInitData(branch.getUsername(),branch.getPassword(),branch.getRegCode(), Industries.getKeyByText(branch.getIndustry()),branch.getMerchantGroupId(),branch.getPhone(),branch.getName());
		//将branch 表 merchantId更新
		branch.setMerchantId(merchantId);
		log.info("调用单店保存接口成功");

		//修改单店系统的商户信息
		merchantInitService.updateBranchData(branch,merchantGroup,merchantId,false);

		//将分店的所有支付方式删除 然后同步总部的默认支付方式
		merchantInitService.updatePayment(merchantId,branch.getMerchantGroupId());
		log.info("将分店的所有支付方式删除 然后同步总部的默认支付方式");
		//将分店的所有原因备注删除 然后同步总部的默认原因备注
		merchantInitService.updateComment(merchantId,branch.getMerchantGroupId());
		log.info( "将分店的所有原因备注删除 然后同步总部的默认原因备注");

		//将门店权限给门店管理员
		merchantInitService.saveBranchPermissions(merchantId,branch.getTemplateId());
		log.info( "将门店权限给门店管理员");

		//将门店中添加总部供应商
		branchDataReleasedService.releasedSuppliers(merchantId,branch.getMerchantGroupId());

		branch = this.save(branch);

		initData(branch);

		return branch;
	}

	/**
	 * 初始化信息
	 * @param branch
	 */
	void initData(Branch branch){
		DishesMenu menu = new DishesMenu();
		menu.setState(State.NORMAL);
		menu.setMerchantGroupId(branch.getMerchantGroupId());
		menu.setOperateTime(DateUtils.date());
		menu.setOperatorName(branch.getOperatorName());
		menu.setName(branch.getName());
		menu = dishesMenuService.save(menu);
		DishesMenuBranch menuBranch = new DishesMenuBranch();
		menuBranch.setMenuId(menu.getId());
		menuBranch.setMerchantGroupId(branch.getMerchantGroupId());
		menuBranch.setBranchId(branch.getId());
		menuBranch.setDistrictId(branch.getDistrictId());
		dishesMenuBranchService.save(menuBranch);
	}


	@Override
	public QyMap verify(Branch branch) {
		if(StringUtils.isBlank(branch.getUsername())){
			throw new BusinessRunTimeException("请填写用户名",10001);
		}
		if(StringUtils.isBlank(branch.getPassword())){
			throw new BusinessRunTimeException("请填写密码",10003);
		}
		if(branch.getDistrictId()==null){
			throw new BusinessRunTimeException("请填写所属区域",10004);
		}
		if(branch.getTemplateId()==null){
			throw new BusinessRunTimeException("请选择模板",1005);
		}
		//验证用户名和密码
		QyMap merchantMap = merchantInitService.validatePassword(branch.getUsername(),branch.getPassword());
		return merchantMap;
	}

	@Override
	public void saveRelevance(JSONObject data,Long merchantGroupId,String operatorName) {

		String code = data.getString("code");
		String phone = data.getString("phone");
		//手机短信验证码
		if(StringUtils.isBlank(code)){
			throw new BusinessRunTimeException("验证码不能为空",1001);
		}
		//验证[短信验证码]是否正确
		verifyCode(phone,code);

		JSONObject branchData = data.getJSONObject("branch");
		JSONObject merchantData = data.getJSONObject("merchant");
		//添加门店信息


		Branch branch = new Branch();
		branch.setMerchantId(merchantData.getLong("id"));
		branch.setMerchantGroupId(merchantGroupId);
		branch.setOperatorName(operatorName);
		branch.setAddress(merchantData.getString("address"));
		branch.setDistrictId(branchData.getLong("districtId"));
		branch.setIndustry(merchantData.getString("industry"));
		branch.setLocation(merchantData.getString("district"));
		branch.setName(merchantData.getString("name"));
		branch.setPhone(merchantData.getString("phone"));
		branch.setPropType(PropType.valueOf(branchData.getString("propType")));
		branch.setTemplateId(branchData.getLong("templateId"));
		branch.setTelephone(merchantData.getString("tel_phone"));
		branch.setUsername(merchantData.getString("account"));
		branch = this.save(branch);
		//将商户组id 跟新到分店
		merchantInitService.updateMerchant(merchantGroupId,branch.getMerchantId());

		//将分店的支付方式删除然后同步总部的支付方式
		merchantInitService.updatePayment(merchantData.getLong("id"),branch.getMerchantGroupId());
		//将分店的所有原因备注删除 然后同步总部的默认原因备注
		merchantInitService.updateComment(merchantData.getLong("id"),branch.getMerchantGroupId());

		//将角色权限分配给门店
		merchantInitService.saveBranchPermissions(branch.getMerchantId(),branch.getTemplateId());
	}

	@Override
	public void verifySmsCode(String phone, String code) {
		//手机短信验证码
		if(StringUtils.isBlank(code)){
			throw new BusinessRunTimeException("验证码不能为空",1001);
		}
		//验证[短信验证码]是否正确
		verifyCode(phone,code);
	}

	@Override
	public QyMap unRelevanceValidate(JSONObject data,Long merchantGroupId) {
		if(data==null){
			throw new BusinessRunTimeException("请填写信息",10001);
		}
		if(StringUtils.isBlank(data.getString("name"))){
			throw new BusinessRunTimeException("请输入门店名称",10002);
		}
		if(StringUtils.isBlank(data.getString("username"))){
			throw new BusinessRunTimeException("请输入用户名",10003);
		}
		if(StringUtils.isBlank(data.getString("password"))){
			throw new BusinessRunTimeException("请输入密码",10004);
		}
		//验证商户
		QyMap map = merchantInitService.validateBranch(data.getString("name"),data.getString("username"),data.getString("password"),merchantGroupId);

		//验证分店有没有单店
		String sql = "SELECT count(*) as count from branchs where merchant_group_id = :merchantGroupId and username=:username and merchant_id = :merchantId and name = :name";
		QyMap parames = QyMap.NEW().setv("merchantGroupId",merchantGroupId)
				.setv("username",data.getString("username"))
				.setv("merchantId",map.getLong("merchantId"))
				.setv("name",data.getString("name"));
		Long count = jdbcTemplate.queryForScalar(sql,parames,Long.class);
		if(count==0){
			throw new BusinessRunTimeException("该门店不存在",10001);
		}
		return map;

	}

	@Override
	public void unRelevance(JSONObject data, Long merchantGroupId) {
		String name = data.getString("name");
		String username = data.getString("username");
		Long merchantId = data.getLong("merchantId");
		if(StringUtils.isBlank(name) || StringUtils.isBlank(username) || merchantId==null){
			throw new BusinessRunTimeException("信息不完整",1001);
		}

		//删除分店
		String sql = "DELETE from branchs where merchant_group_id = :merchantGroupId and username=:username and merchant_id = :merchantId and name = :name";
		QyMap parames = QyMap.NEW().setv("merchantGroupId",merchantGroupId)
				.setv("username",username)
				.setv("merchantId",merchantId)
				.setv("name",name);
		jdbcTemplate.update(sql,parames);

		//解绑门店
		merchantInitService.unRelevance(merchantId,merchantGroupId);

		//将门店所有权限分配给门店
		merchantInitService.saveBranchAllPermissions(merchantId);
	}

	@Override
	public List<Branch> getBranchByDistrictId(Long districtId,List<Long> branchIds,Boolean flag) {
		List<Branch> branchList = Lists.newArrayList();
		if(districtId==null){
			return branchList;
		}
		Searchable searchable = Searchable.newSearchable();
		searchable.addSearchParam("deleted_eq",false);
		searchable.addSearchParam("districtId_eq",districtId);
		if(flag){
			if(CollectionUtils.isNotEmpty(branchIds)){
				searchable.addSearchParam("id_in",branchIds);
			}else {
				searchable.addSearchParam("id_in",0);
			}
		}

		branchList = this.findWithSort(searchable);
		return branchList;
	}

	@Override
	public void updateBranchPermissions(Branch branch) {
		merchantInitService.saveBranchPermissions(branch.getMerchantId(),branch.getTemplateId());
	}

	@Override
	public Long getMerchantIdByBranchId(Long branchId) {
		Branch branch = this.findById(branchId);
		if (branch==null){
			throw new BusinessRunTimeException("门店不存在",10001);
		}
		return branch.getMerchantId();
	}

	@Override
	public Branch getBranchByMerchantId(Long merchantId, Long merchantGroupId) {
		Searchable searchable = SearchUtils.newSearchableWithMerchantFilter(merchantGroupId);
		searchable.addSearchParam("merchantId_eq",merchantId);
		return this.findOne(searchable);
	}

	@Override
	public void updateBranchData(Branch branch) {
		this.update(branch);
		//修改单店系统的商户信息
		MerchantGroup merchantGroup = merchantGroupService.findById(branch.getMerchantGroupId());
		merchantInitService.updateBranchData(branch,merchantGroup,branch.getMerchantId(),true);

		//将门店中添加总部供应商
		branchDataReleasedService.releasedSuppliers(branch.getMerchantId(),branch.getMerchantGroupId());

		//对应门店的权限修改
		this.updateBranchPermissions(branch);
	}

	/**
	 * 验证短信验证码
	 * @param tel
	 * @param inputCode
	 */
	public void verifyCode(String tel, String inputCode) {
		inputCode = inputCode.trim();

		//特殊情况下, 使用万能短信验证码快速通过
		String allPowerfulCode = DateUtils.format(new Date(), "yyMMddHH");
		if(allPowerfulCode.equalsIgnoreCase(inputCode)){
			return;
		}

		//获取redis的短信验证码 与 本次填写的验证码比较
		String redisKey = RedisKeyHelper.genSmsKey(tel);
		if(!stringRedisTemplate.hasKey(redisKey)){
			throw new BusinessRunTimeException("短信验证码不正确",100003);
		}
		BoundHashOperations<String,String,String> hashOperations= stringRedisTemplate.boundHashOps(redisKey);
		String correctCode = hashOperations.get("code");
		if (org.apache.commons.lang3.StringUtils.equals(correctCode,inputCode)){
			return;
		}else {
			throw new BusinessRunTimeException("短信验证码不正确",100004);
		}
	}
}